package sample;

public class Positive {
    /*
    我们获取到收藏ID的流
    我们 异步地转换 它们（ID） 为 Favorite 对象（使用 flatMap），现在我们有了 `Favorite`流。
    一旦 Favorite 为空，切换到 suggestionService。
    我们只关注流中的最多5个元素。
    最后，我们希望在 UI 线程中进行处理。
    通过描述对数据的最终处理（在 UI 中显示）和对错误的处理（显示在 popup 中）来触发（subscribe）。
     */
    /*
    userService.getFavorites(userId)
        .flatMap(favoriteService::getDetails)
        .switchIfEmpty(suggestionService.getSuggestions())
        .take(5)
        .publishOn(UiUtils.uiThreadScheduler())
        .subscribe(uiList::show, UiUtils::errorPopup);*/
    // 如果你想确保“收藏的ID”的数据在800ms内获得（如果超时，从缓存中获取）呢？在基于回调的代码中， 会比较复杂。
    // 但 Reactor 中就很简单，在处理链中增加一个 timeout 的操作符即可。
    /*
    如果流在超时时限没有发出（emit）任何值，则发出错误（error）。
    一旦收到错误，交由 cacheService 处理。
    处理链后边的内容与上例类似。
     */
    /*
    userService.getFavorites(userId)
           .timeout(Duration.ofMillis(800))
           .onErrorResume(cacheService.cachedFavoritesFor(userId))
           .flatMap(favoriteService::getDetails)
           .switchIfEmpty(suggestionService.getSuggestions())
           .take(5)
           .publishOn(UiUtils.uiThreadScheduler())
           .subscribe(uiList::show, UiUtils::errorPopup);
     */


    /*
    以一个 Future 开始，其中封装了后续将获取和处理的 ID 的 list。
    获取到 list 后边进一步对其启动异步处理任务。
    对于 list 中的每一个元素：
    异步地得到相应的 name。
    异步地得到相应的 statistics。
    将两个结果一一组合。
    我们现在有了一个 list，元素是 Future（表示组合的任务，类型是 CompletableFuture），为了执行这些任务， 我们需要将这个 list（元素构成的流） 转换为数组（List）。
    将这个数组传递给 CompletableFuture.allOf，返回一个 Future ，当所以任务都完成了，那么这个 Future 也就完成了。
    有点麻烦的地方在于 allOf 返回的是 CompletableFuture<Void>，所以我们遍历这个 Future 的`List`， ，然后使用 join() 来手机它们的结果（不会导致阻塞，因为 AllOf 确保这些 Future 全部完成）
    一旦整个异步流水线被触发，我们等它完成处理，然后返回结果列表。
     */
    /*
    CompletableFuture<List<String>> ids = ifhIds();

    CompletableFuture<List<String>> result = ids.thenComposeAsync(l -> {
            Stream<CompletableFuture<String>> zip =
                            l.stream().map(i -> {
                                                     CompletableFuture<String> nameTask = ifhName(i);
                                                     CompletableFuture<Integer> statTask = ifhStat(i);

                                                     return nameTask.thenCombineAsync(statTask, (name, stat) -> "Name " + name + " has stats " + stat);
                                             });
            List<CompletableFuture<String>> combinationList = zip.collect(Collectors.toList());
            CompletableFuture<String>[] combinationArray = combinationList.toArray(new CompletableFuture[combinationList.size()]);

            CompletableFuture<Void> allDone = CompletableFuture.allOf(combinationArray);
            return allDone.thenApply(v -> combinationList.stream()
                                                                                                     .map(CompletableFuture::join)
                                                                                                     .collect(Collectors.toList()));
    });

    List<String> results = result.join();
    assertThat(results).contains(
                                    "Name NameJoe has stats 103",
                                    "Name NameBart has stats 104",
                                    "Name NameHenry has stats 105",
                                    "Name NameNicole has stats 106",
                                    "Name NameABSLAJNFOAJNFOANFANSF has stats 121");
     */


    /*
    Flux<String> ids = ifhrIds();

    Flux<String> combinations =
                    ids.flatMap(id -> {
                            Mono<String> nameTask = ifhrName(id);
                            Mono<Integer> statTask = ifhrStat(id);

                            return nameTask.zipWith(statTask,
                                            (name, stat) -> "Name " + name + " has stats " + stat);
                    });

    Mono<List<String>> result = combinations.collectList();

    List<String> results = result.block();
    assertThat(results).containsExactly(
                    "Name NameJoe has stats 103",
                    "Name NameBart has stats 104",
                    "Name NameHenry has stats 105",
                    "Name NameNicole has stats 106",
                    "Name NameABSLAJNFOAJNFOANFANSF has stats 121"
    );
     */
}
